home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_kernel_source / KERNEL / MODULE.C < prev    next >
C/C++ Source or Header  |  1999-09-17  |  22KB  |  1,015 lines

  1. #include <linux/config.h>
  2. #include <linux/mm.h>
  3. #include <linux/module.h>
  4. #include <asm/uaccess.h>
  5. #include <linux/vmalloc.h>
  6. #include <linux/smp_lock.h>
  7. #include <asm/pgtable.h>
  8. #include <linux/init.h>
  9.  
  10. /*
  11.  * Originally by Anonymous (as far as I know...)
  12.  * Linux version by Bas Laarhoven <bas@vimec.nl>
  13.  * 0.99.14 version by Jon Tombs <jon@gtex02.us.es>,
  14.  * Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
  15.  * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
  16.  *
  17.  * This source is covered by the GNU GPL, the same as all kernel sources.
  18.  */
  19.  
  20. #ifdef CONFIG_MODULES        /* a *big* #ifdef block... */
  21.  
  22. extern struct module_symbol __start___ksymtab[];
  23. extern struct module_symbol __stop___ksymtab[];
  24.  
  25. extern const struct exception_table_entry __start___ex_table[];
  26. extern const struct exception_table_entry __stop___ex_table[];
  27.  
  28. static struct module kernel_module =
  29. {
  30.     sizeof(struct module),    /* size_of_struct */
  31.     NULL,            /* next */
  32.     "",            /* name */
  33.     0,            /* size */
  34.     {ATOMIC_INIT(1)},    /* usecount */
  35.     MOD_RUNNING,        /* flags */
  36.     0,            /* nsyms -- to filled in in init_modules */
  37.     0,            /* ndeps */
  38.     __start___ksymtab,    /* syms */
  39.     NULL,            /* deps */
  40.     NULL,            /* refs */
  41.     NULL,            /* init */
  42.     NULL,            /* cleanup */
  43.     __start___ex_table,    /* ex_table_start */
  44.     __stop___ex_table,    /* ex_table_end */
  45.     /* Rest are NULL */
  46. };
  47.  
  48. struct module *module_list = &kernel_module;
  49.  
  50. static long get_mod_name(const char *user_name, char **buf);
  51. static void put_mod_name(char *buf);
  52. static struct module *find_module(const char *name);
  53. static void free_module(struct module *, int tag_freed);
  54.  
  55.  
  56. /*
  57.  * Called at boot time
  58.  */
  59.  
  60. __initfunc(void init_modules(void))
  61. {
  62.     kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
  63.  
  64. #ifdef __alpha__
  65.     __asm__("stq $29,%0" : "=m"(kernel_module.gp));
  66. #endif
  67. }
  68.  
  69. /*
  70.  * Copy the name of a module from user space.
  71.  */
  72.  
  73. static inline long
  74. get_mod_name(const char *user_name, char **buf)
  75. {
  76.     unsigned long page;
  77.     long retval;
  78.  
  79.     if ((unsigned long)user_name >= TASK_SIZE
  80.         && !segment_eq(get_fs (), KERNEL_DS))
  81.         return -EFAULT;
  82.  
  83.     page = __get_free_page(GFP_KERNEL);
  84.     if (!page)
  85.         return -ENOMEM;
  86.  
  87.     retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
  88.     if (retval > 0) {
  89.         if (retval < PAGE_SIZE) {
  90.             *buf = (char *)page;
  91.             return retval;
  92.         }
  93.         retval = -ENAMETOOLONG;
  94.     } else if (!retval)
  95.         retval = -EINVAL;
  96.  
  97.     free_page(page);
  98.     return retval;
  99. }
  100.  
  101. static inline void
  102. put_mod_name(char *buf)
  103. {
  104.     free_page((unsigned long)buf);
  105. }
  106.  
  107. /*
  108.  * Allocate space for a module.
  109.  */
  110.  
  111. asmlinkage unsigned long
  112. sys_create_module(const char *name_user, size_t size)
  113. {
  114.     char *name;
  115.     long namelen, error;
  116.     struct module *mod;
  117.  
  118.     lock_kernel();
  119.     if (!capable(CAP_SYS_MODULE)) {
  120.         error = -EPERM;
  121.         goto err0;
  122.     }
  123.     if ((namelen = get_mod_name(name_user, &name)) < 0) {
  124.         error = namelen;
  125.         goto err0;
  126.     }
  127.     if (size < sizeof(struct module)+namelen) {
  128.         error = -EINVAL;
  129.         goto err1;
  130.     }
  131.     if (find_module(name) != NULL) {
  132.         error = -EEXIST;
  133.         goto err1;
  134.     }
  135.     if ((mod = (struct module *)module_map(size)) == NULL) {
  136.         error = -ENOMEM;
  137.         goto err1;
  138.     }
  139.  
  140.     memset(mod, 0, sizeof(*mod));
  141.     mod->size_of_struct = sizeof(*mod);
  142.     mod->next = module_list;
  143.     mod->name = (char *)(mod + 1);
  144.     mod->size = size;
  145.     memcpy((char*)(mod+1), name, namelen+1);
  146.  
  147.     put_mod_name(name);
  148.  
  149.     module_list = mod;    /* link it in */
  150.  
  151.     error = (long) mod;
  152.     goto err0;
  153. err1:
  154.     put_mod_name(name);
  155. err0:
  156.     unlock_kernel();
  157.     return error;
  158. }
  159.  
  160. /*
  161.  * Initialize a module.
  162.  */
  163.  
  164. asmlinkage int
  165. sys_init_module(const char *name_user, struct module *mod_user)
  166. {
  167.     struct module mod_tmp, *mod;
  168.     char *name, *n_name;
  169.     long namelen, n_namelen, i, error = -EPERM;
  170.     unsigned long mod_user_size;
  171.     struct module_ref *dep;
  172.  
  173.     lock_kernel();
  174.     if (!capable(CAP_SYS_MODULE))
  175.         goto err0;
  176.     if ((namelen = get_mod_name(name_user, &name)) < 0) {
  177.         error = namelen;
  178.         goto err0;
  179.     }
  180.     if ((mod = find_module(name)) == NULL) {
  181.         error = -ENOENT;
  182.         goto err1;
  183.     }
  184.  
  185.     /* Check module header size.  We allow a bit of slop over the 
  186.        size we are familiar with to cope with a version of insmod
  187.        for a newer kernel.  But don't over do it. */
  188.     if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0)
  189.         goto err1;
  190.     if (mod_user_size < (unsigned long)&((struct module *)0L)->persist_start
  191.         || mod_user_size > sizeof(struct module) + 16*sizeof(void*)) {
  192.         printk(KERN_ERR "init_module: Invalid module header size.\n"
  193.                KERN_ERR "A new version of the modutils is likely "
  194.                 "needed.\n");
  195.         error = -EINVAL;
  196.         goto err1;
  197.     }
  198.  
  199.     /* Hold the current contents while we play with the user's idea
  200.        of righteousness.  */
  201.     mod_tmp = *mod;
  202.  
  203.     error = copy_from_user(mod, mod_user, sizeof(struct module));
  204.     if (error) {
  205.         error = -EFAULT;
  206.         goto err2;
  207.     }
  208.  
  209.     /* Sanity check the size of the module.  */
  210.     error = -EINVAL;
  211.  
  212.     if (mod->size > mod_tmp.size) {
  213.         printk(KERN_ERR "init_module: Size of initialized module "
  214.                 "exceeds size of created module.\n");
  215.         goto err2;
  216.     }
  217.  
  218.     /* Make sure all interesting pointers are sane.  */
  219.  
  220. #define bound(p, n, m)  ((unsigned long)(p) >= (unsigned long)(m+1) &&  \
  221.              (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
  222.  
  223.     if (!bound(mod->name, namelen, mod)) {
  224.         printk(KERN_ERR "init_module: mod->name out of bounds.\n");
  225.         goto err2;
  226.     }
  227.     if (mod->nsyms && !bound(mod->syms, mod->nsyms, mod)) {
  228.         printk(KERN_ERR "init_module: mod->syms out of bounds.\n");
  229.         goto err2;
  230.     }
  231.     if (mod->ndeps && !bound(mod->deps, mod->ndeps, mod)) {
  232.         printk(KERN_ERR "init_module: mod->deps out of bounds.\n");
  233.         goto err2;
  234.     }
  235.     if (mod->init && !bound(mod->init, 0, mod)) {
  236.         printk(KERN_ERR "init_module: mod->init out of bounds.\n");
  237.         goto err2;
  238.     }
  239.     if (mod->cleanup && !bound(mod->cleanup, 0, mod)) {
  240.         printk(KERN_ERR "init_module: mod->cleanup out of bounds.\n");
  241.         goto err2;
  242.     }
  243.     if (mod->ex_table_start > mod->ex_table_end
  244.         || (mod->ex_table_start &&
  245.         !((unsigned long)mod->ex_table_start >= (unsigned long)(mod+1)
  246.           && ((unsigned long)mod->ex_table_end
  247.               < (unsigned long)mod + mod->size)))
  248.         || (((unsigned long)mod->ex_table_start
  249.          - (unsigned long)mod->ex_table_end)
  250.         % sizeof(struct exception_table_entry))) {
  251.         printk(KERN_ERR "init_module: mod->ex_table_* invalid.\n");
  252.         goto err2;
  253.     }
  254.     if (mod->flags & ~MOD_AUTOCLEAN) {
  255.         printk(KERN_ERR "init_module: mod->flags invalid.\n");
  256.         goto err2;
  257.     }
  258. #ifdef __alpha__
  259.     if (!bound(mod->gp - 0x8000, 0, mod)) {
  260.         printk(KERN_ERR "init_module: mod->gp out of bounds.\n");
  261.         goto err2;
  262.     }
  263. #endif
  264.     if (mod_member_present(mod, can_unload)
  265.         && mod->can_unload && !bound(mod->can_unload, 0, mod)) {
  266.         printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");
  267.         goto err2;
  268.     }
  269.  
  270. #undef bound
  271.  
  272.     /* Check that the user isn't doing something silly with the name.  */
  273.  
  274.     if ((n_namelen = get_mod_name(mod->name - (unsigned long)mod
  275.                       + (unsigned long)mod_user,
  276.                       &n_name)) < 0) {
  277.         error = n_namelen;
  278.         goto err2;
  279.     }
  280.     if (namelen != n_namelen || strcmp(n_name, mod_tmp.name) != 0) {
  281.         printk(KERN_ERR "init_module: changed module name to "
  282.                 "`%s' from `%s'\n",
  283.                n_name, mod_tmp.name);
  284.         goto err3;
  285.     }
  286.  
  287.     /* Ok, that's about all the sanity we can stomach; copy the rest.  */
  288.  
  289.     if (copy_from_user(mod+1, mod_user+1, mod->size-sizeof(*mod))) {
  290.         error = -EFAULT;
  291.         goto err3;
  292.     }
  293.  
  294.     /* On some machines it is necessary to do something here
  295.        to make the I and D caches consistent.  */
  296.     flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
  297.  
  298.     /* Update module references.  */
  299.     mod->next = mod_tmp.next;
  300.     mod->refs = NULL;
  301.     for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
  302.         struct module *o, *d = dep->dep;
  303.  
  304.         /* Make sure the indicated dependencies are really modules.  */
  305.         if (d == mod) {
  306.             printk(KERN_ERR "init_module: self-referential "
  307.                     "dependency in mod->deps.\n");
  308.             goto err3;
  309.         }
  310.  
  311.         for (o = module_list; o != &kernel_module; o = o->next)
  312.             if (o == d) goto found_dep;
  313.  
  314.         printk(KERN_ERR "init_module: found dependency that is "
  315.                 "(no longer?) a module.\n");
  316.         goto err3;
  317.         
  318.     found_dep:
  319.         dep->ref = mod;
  320.         dep->next_ref = d->refs;
  321.         d->refs = dep;
  322.         /* Being referenced by a dependent module counts as a 
  323.            use as far as kmod is concerned.  */
  324.         d->flags |= MOD_USED_ONCE;
  325.     }
  326.  
  327.     /* Free our temporary memory.  */
  328.     put_mod_name(n_name);
  329.     put_mod_name(name);
  330.  
  331.     /* Initialize the module.  */
  332.     atomic_set(&mod->uc.usecount,1);
  333.     if (mod->init && mod->init() != 0) {
  334.         atomic_set(&mod->uc.usecount,0);
  335.         error = -EBUSY;
  336.         goto err0;
  337.     }
  338.     atomic_dec(&mod->uc.usecount);
  339.  
  340.     /* And set it running.  */
  341.     mod->flags |= MOD_RUNNING;
  342.     error = 0;
  343.     goto err0;
  344.  
  345. err3:
  346.     put_mod_name(n_name);
  347. err2:
  348.     *mod = mod_tmp;
  349. err1:
  350.     put_mod_name(name);
  351. err0:
  352.     unlock_kernel();
  353.     return error;
  354. }
  355.  
  356. asmlinkage int
  357. sys_delete_module(const char *name_user)
  358. {
  359.     struct module *mod, *next;
  360.     char *name;
  361.     long error = -EPERM;
  362.     int something_changed;
  363.  
  364.     lock_kernel();
  365.     if (!capable(CAP_SYS_MODULE))
  366.         goto out;
  367.  
  368.     if (name_user) {
  369.         if ((error = get_mod_name(name_user, &name)) < 0)
  370.             goto out;
  371.         if (error == 0) {
  372.             error = -EINVAL;
  373.             put_mod_name(name);
  374.             goto out;
  375.         }
  376.         error = -ENOENT;
  377.         if ((mod = find_module(name)) == NULL) {
  378.             put_mod_name(name);
  379.             goto out;
  380.         }
  381.         put_mod_name(name);
  382.         error = -EBUSY;
  383.          if (mod->refs != NULL || __MOD_IN_USE(mod))
  384.             goto out;
  385.  
  386.         free_module(mod, 0);
  387.         error = 0;
  388.         goto out;
  389.     }
  390.  
  391.     /* Do automatic reaping */
  392. restart:
  393.     something_changed = 0;
  394.     for (mod = module_list; mod != &kernel_module; mod = next) {
  395.         next = mod->next;
  396.         if (mod->refs == NULL
  397.             && (mod->flags & MOD_AUTOCLEAN)
  398.             && (mod->flags & MOD_RUNNING)
  399.             && !(mod->flags & MOD_DELETED)
  400.             && (mod->flags & MOD_USED_ONCE)
  401.             && !__MOD_IN_USE(mod)) {
  402.             if ((mod->flags & MOD_VISITED)
  403.                 && !(mod->flags & MOD_JUST_FREED)) {
  404.                 mod->flags &= ~MOD_VISITED;
  405.             } else {
  406.                 free_module(mod, 1);
  407.                 something_changed = 1;
  408.             }
  409.         }
  410.     }
  411.     if (something_changed)
  412.         goto restart;
  413.     for (mod = module_list; mod != &kernel_module; mod = mod->next)
  414.         mod->flags &= ~MOD_JUST_FREED;
  415.     error = 0;
  416. out:
  417.     unlock_kernel();
  418.     return error;
  419. }
  420.  
  421. /* Query various bits about modules.  */
  422.  
  423. static int
  424. qm_modules(char *buf, size_t bufsize, size_t *ret)
  425. {
  426.     struct module *mod;
  427.     size_t nmod, space, len;
  428.  
  429.     nmod = space = 0;
  430.  
  431.     for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) {
  432.         len = strlen(mod->name)+1;
  433.         if (len > bufsize)
  434.             goto calc_space_needed;
  435.         if (copy_to_user(buf, mod->name, len))
  436.             return -EFAULT;
  437.         buf += len;
  438.         bufsize -= len;
  439.         space += len;
  440.     }
  441.  
  442.     if (put_user(nmod, ret))
  443.         return -EFAULT;
  444.     else
  445.         return 0;
  446.  
  447. calc_space_needed:
  448.     space += len;
  449.     while ((mod = mod->next) != &kernel_module)
  450.         space += strlen(mod->name)+1;
  451.  
  452.     if (put_user(space, ret))
  453.         return -EFAULT;
  454.     else
  455.         return -ENOSPC;
  456. }
  457.  
  458. static int
  459. qm_deps(struct module *mod, char *buf, size_t bufsize, size_t *ret)
  460. {
  461.     size_t i, space, len;
  462.  
  463.     if (mod == &kernel_module)
  464.         return -EINVAL;
  465.     if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
  466.         if (put_user(0, ret))
  467.             return -EFAULT;
  468.         else
  469.             return 0;
  470.  
  471.     space = 0;
  472.     for (i = 0; i < mod->ndeps; ++i) {
  473.         const char *dep_name = mod->deps[i].dep->name;
  474.  
  475.         len = strlen(dep_name)+1;
  476.         if (len > bufsize)
  477.             goto calc_space_needed;
  478.         if (copy_to_user(buf, dep_name, len))
  479.             return -EFAULT;
  480.         buf += len;
  481.         bufsize -= len;
  482.         space += len;
  483.     }
  484.  
  485.     if (put_user(i, ret))
  486.         return -EFAULT;
  487.     else
  488.         return 0;
  489.  
  490. calc_space_needed:
  491.     space += len;
  492.     while (++i < mod->ndeps)
  493.         space += strlen(mod->deps[i].dep->name)+1;
  494.  
  495.     if (put_user(space, ret))
  496.         return -EFAULT;
  497.     else
  498.         return -ENOSPC;
  499. }
  500.  
  501. static int
  502. qm_refs(struct module *mod, char *buf, size_t bufsize, size_t *ret)
  503. {
  504.     size_t nrefs, space, len;
  505.     struct module_ref *ref;
  506.  
  507.     if (mod == &kernel_module)
  508.         return -EINVAL;
  509.     if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
  510.         if (put_user(0, ret))
  511.             return -EFAULT;
  512.         else
  513.             return 0;
  514.  
  515.     space = 0;
  516.     for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
  517.         const char *ref_name = ref->ref->name;
  518.  
  519.         len = strlen(ref_name)+1;
  520.         if (len > bufsize)
  521.             goto calc_space_needed;
  522.         if (copy_to_user(buf, ref_name, len))
  523.             return -EFAULT;
  524.         buf += len;
  525.         bufsize -= len;
  526.         space += len;
  527.     }
  528.  
  529.     if (put_user(nrefs, ret))
  530.         return -EFAULT;
  531.     else
  532.         return 0;
  533.  
  534. calc_space_needed:
  535.     space += len;
  536.     while ((ref = ref->next_ref) != NULL)
  537.         space += strlen(ref->ref->name)+1;
  538.  
  539.     if (put_user(space, ret))
  540.         return -EFAULT;
  541.     else
  542.         return -ENOSPC;
  543. }
  544.  
  545. static int
  546. qm_symbols(struct module *mod, char *buf, size_t bufsize, size_t *ret)
  547. {
  548.     size_t i, space, len;
  549.     struct module_symbol *s;
  550.     char *strings;
  551.     unsigned long *vals;
  552.  
  553.     if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
  554.         if (put_user(0, ret))
  555.             return -EFAULT;
  556.         else
  557.             return 0;
  558.  
  559.     space = mod->nsyms * 2*sizeof(void *);
  560.  
  561.     i = len = 0;
  562.     s = mod->syms;
  563.  
  564.     if (space > bufsize)
  565.         goto calc_space_needed;
  566.  
  567.     if (!access_ok(VERIFY_WRITE, buf, space))
  568.         return -EFAULT;
  569.  
  570.     bufsize -= space;
  571.     vals = (unsigned long *)buf;
  572.     strings = buf+space;
  573.  
  574.     for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
  575.         len = strlen(s->name)+1;
  576.         if (len > bufsize)
  577.             goto calc_space_needed;
  578.  
  579.         if (copy_to_user(strings, s->name, len)
  580.             || __put_user(s->value, vals+0)
  581.             || __put_user(space, vals+1))
  582.             return -EFAULT;
  583.  
  584.         strings += len;
  585.         bufsize -= len;
  586.         space += len;
  587.     }
  588.  
  589.     if (put_user(i, ret))
  590.         return -EFAULT;
  591.     else
  592.         return 0;
  593.  
  594. calc_space_needed:
  595.     for (; i < mod->nsyms; ++i, ++s)
  596.         space += strlen(s->name)+1;
  597.  
  598.     if (put_user(space, ret))
  599.         return -EFAULT;
  600.     else
  601.         return -ENOSPC;
  602. }
  603.  
  604. static int
  605. qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret)
  606. {
  607.     int error = 0;
  608.  
  609.     if (mod == &kernel_module)
  610.         return -EINVAL;
  611.  
  612.     if (sizeof(struct module_info) <= bufsize) {
  613.         struct module_info info;
  614.         info.addr = (unsigned long)mod;
  615.         info.size = mod->size;
  616.         info.flags = mod->flags;
  617.         info.usecount = (mod_member_present(mod, can_unload)
  618.                  && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount));
  619.  
  620.         if (copy_to_user(buf, &info, sizeof(struct module_info)))
  621.             return -EFAULT;
  622.     } else
  623.         error = -ENOSPC;
  624.  
  625.     if (put_user(sizeof(struct module_info), ret))
  626.         return -EFAULT;
  627.  
  628.     return error;
  629. }
  630.  
  631. asmlinkage int
  632. sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
  633.          size_t *ret)
  634. {
  635.     struct module *mod;
  636.     int err;
  637.  
  638.     lock_kernel();
  639.     if (name_user == NULL)
  640.         mod = &kernel_module;
  641.     else {
  642.         long namelen;
  643.         char *name;
  644.  
  645.         if ((namelen = get_mod_name(name_user, &name)) < 0) {
  646.             err = namelen;
  647.             goto out;
  648.         }
  649.         err = -ENOENT;
  650.         if (namelen == 0)
  651.             mod = &kernel_module;
  652.         else if ((mod = find_module(name)) == NULL) {
  653.             put_mod_name(name);
  654.             goto out;
  655.         }
  656.         put_mod_name(name);
  657.     }
  658.  
  659.     switch (which)
  660.     {
  661.     case 0:
  662.         err = 0;
  663.         break;
  664.     case QM_MODULES:
  665.         err = qm_modules(buf, bufsize, ret);
  666.         break;
  667.     case QM_DEPS:
  668.         err = qm_deps(mod, buf, bufsize, ret);
  669.         break;
  670.     case QM_REFS:
  671.         err = qm_refs(mod, buf, bufsize, ret);
  672.         break;
  673.     case QM_SYMBOLS:
  674.         err = qm_symbols(mod, buf, bufsize, ret);
  675.         break;
  676.     case QM_INFO:
  677.         err = qm_info(mod, buf, bufsize, ret);
  678.         break;
  679.     default:
  680.         err = -EINVAL;
  681.         break;
  682.     }
  683. out:
  684.     unlock_kernel();
  685.     return err;
  686. }
  687.  
  688. /*
  689.  * Copy the kernel symbol table to user space.  If the argument is
  690.  * NULL, just return the size of the table.
  691.  *
  692.  * This call is obsolete.  New programs should use query_module+QM_SYMBOLS
  693.  * which does not arbitrarily limit the length of symbols.
  694.  */
  695.  
  696. asmlinkage int
  697. sys_get_kernel_syms(struct kernel_sym *table)
  698. {
  699.     struct module *mod;
  700.     int i;
  701.     struct kernel_sym ksym;
  702.  
  703.     lock_kernel();
  704.     for (mod = module_list, i = 0; mod; mod = mod->next) {
  705.         /* include the count for the module name! */
  706.         i += mod->nsyms + 1;
  707.     }
  708.  
  709.     if (table == NULL)
  710.         goto out;
  711.  
  712.     /* So that we don't give the user our stack content */
  713.     memset (&ksym, 0, sizeof (ksym));
  714.  
  715.     for (mod = module_list, i = 0; mod; mod = mod->next) {
  716.         struct module_symbol *msym;
  717.         unsigned int j;
  718.  
  719.         if ((mod->flags & (MOD_RUNNING|MOD_DELETED)) != MOD_RUNNING)
  720.             continue;
  721.  
  722.         /* magic: write module info as a pseudo symbol */
  723.         ksym.value = (unsigned long)mod;
  724.         ksym.name[0] = '#';
  725.         strncpy(ksym.name+1, mod->name, sizeof(ksym.name)-1);
  726.         ksym.name[sizeof(ksym.name)-1] = '\0';
  727.  
  728.         if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
  729.             goto out;
  730.         ++i, ++table;
  731.  
  732.         if (mod->nsyms == 0)
  733.             continue;
  734.  
  735.         for (j = 0, msym = mod->syms; j < mod->nsyms; ++j, ++msym) {
  736.             ksym.value = msym->value;
  737.             strncpy(ksym.name, msym->name, sizeof(ksym.name));
  738.             ksym.name[sizeof(ksym.name)-1] = '\0';
  739.  
  740.             if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
  741.                 goto out;
  742.             ++i, ++table;
  743.         }
  744.     }
  745. out:
  746.     unlock_kernel();
  747.     return i;
  748. }
  749.  
  750. /*
  751.  * Look for a module by name, ignoring modules marked for deletion.
  752.  */
  753.  
  754. static struct module *
  755. find_module(const char *name)
  756. {
  757.     struct module *mod;
  758.  
  759.     for (mod = module_list; mod ; mod = mod->next) {
  760.         if (mod->flags & MOD_DELETED)
  761.             continue;
  762.         if (!strcmp(mod->name, name))
  763.             break;
  764.     }
  765.  
  766.     return mod;
  767. }
  768.  
  769. /*
  770.  * Free the given module.
  771.  */
  772.  
  773. static void
  774. free_module(struct module *mod, int tag_freed)
  775. {
  776.     struct module_ref *dep;
  777.     unsigned i;
  778.  
  779.     /* Let the module clean up.  */
  780.  
  781.     mod->flags |= MOD_DELETED;
  782.     if (mod->flags & MOD_RUNNING) 
  783.     {
  784.         if(mod->cleanup)
  785.             mod->cleanup();
  786.         mod->flags &= ~MOD_RUNNING;
  787.     }
  788.  
  789.     /* Remove the module from the dependency lists.  */
  790.  
  791.     for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
  792.         struct module_ref **pp;
  793.         for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref)
  794.             continue;
  795.         *pp = dep->next_ref;
  796.         if (tag_freed && dep->dep->refs == NULL)
  797.             dep->dep->flags |= MOD_JUST_FREED;
  798.     }
  799.  
  800.     /* And from the main module list.  */
  801.  
  802.     if (mod == module_list) {
  803.         module_list = mod->next;
  804.     } else {
  805.         struct module *p;
  806.         for (p = module_list; p->next != mod; p = p->next)
  807.             continue;
  808.         p->next = mod->next;
  809.     }
  810.  
  811.     /* And free the memory.  */
  812.  
  813.     module_unmap(mod);
  814. }
  815.  
  816. /*
  817.  * Called by the /proc file system to return a current list of modules.
  818.  */
  819.  
  820. int get_module_list(char *p)
  821. {
  822.     size_t left = PAGE_SIZE;
  823.     struct module *mod;
  824.     char tmpstr[64];
  825.     struct module_ref *ref;
  826.  
  827.     for (mod = module_list; mod != &kernel_module; mod = mod->next) {
  828.         long len;
  829.         const char *q;
  830.  
  831. #define safe_copy_str(str, len)                        \
  832.         do {                            \
  833.             if (left < len)                    \
  834.                 goto fini;                \
  835.             memcpy(p, str, len); p += len, left -= len;    \
  836.         } while (0)
  837. #define safe_copy_cstr(str)    safe_copy_str(str, sizeof(str)-1)
  838.  
  839.             len = strlen(mod->name);
  840.         safe_copy_str(mod->name, len);
  841.  
  842.         if ((len = 20 - len) > 0) {
  843.             if (left < len)
  844.                 goto fini;
  845.             memset(p, ' ', len);
  846.             p += len;
  847.             left -= len;
  848.         }
  849.  
  850.         len = sprintf(tmpstr, "%8lu", mod->size);
  851.         safe_copy_str(tmpstr, len);
  852.  
  853.         if (mod->flags & MOD_RUNNING) {
  854.             len = sprintf(tmpstr, "%4ld",
  855.                       (mod_member_present(mod, can_unload)
  856.                        && mod->can_unload
  857.                        ? -1L : (long)atomic_read(&mod->uc.usecount)));
  858.             safe_copy_str(tmpstr, len);
  859.         }
  860.  
  861.         if (mod->flags & MOD_DELETED)
  862.             safe_copy_cstr(" (deleted)");
  863.         else if (mod->flags & MOD_RUNNING) {
  864.             if (mod->flags & MOD_AUTOCLEAN)
  865.                 safe_copy_cstr(" (autoclean)");
  866.             if (!(mod->flags & MOD_USED_ONCE))
  867.                 safe_copy_cstr(" (unused)");
  868.         } else
  869.             safe_copy_cstr(" (uninitialized)");
  870.  
  871.         if ((ref = mod->refs) != NULL) {
  872.             safe_copy_cstr(" [");
  873.             while (1) {
  874.                 q = ref->ref->name;
  875.                 len = strlen(q);
  876.                 safe_copy_str(q, len);
  877.  
  878.                 if ((ref = ref->next_ref) != NULL)
  879.                     safe_copy_cstr(" ");
  880.                 else
  881.                     break;
  882.             }
  883.             safe_copy_cstr("]");
  884.         }
  885.         safe_copy_cstr("\n");
  886.  
  887. #undef safe_copy_str
  888. #undef safe_copy_cstr
  889.     }
  890.  
  891. fini:
  892.     return PAGE_SIZE - left;
  893. }
  894.  
  895. /*
  896.  * Called by the /proc file system to return a current list of ksyms.
  897.  */
  898.  
  899. int
  900. get_ksyms_list(char *buf, char **start, off_t offset, int length)
  901. {
  902.     struct module *mod;
  903.     char *p = buf;
  904.     int len     = 0;    /* code from  net/ipv4/proc.c */
  905.     off_t pos   = 0;
  906.     off_t begin = 0;
  907.  
  908.     for (mod = module_list; mod; mod = mod->next) {
  909.         unsigned i;
  910.         struct module_symbol *sym;
  911.  
  912.         if (!(mod->flags & MOD_RUNNING) || (mod->flags & MOD_DELETED))
  913.             continue;
  914.  
  915.         for (i = mod->nsyms, sym = mod->syms; i > 0; --i, ++sym) {
  916.             p = buf + len;
  917.             if (*mod->name) {
  918.                 len += sprintf(p, "%0*lx %s\t[%s]\n",
  919.                            (int)(2*sizeof(void*)),
  920.                            sym->value, sym->name,
  921.                            mod->name);
  922.             } else {
  923.                 len += sprintf(p, "%0*lx %s\n",
  924.                            (int)(2*sizeof(void*)),
  925.                            sym->value, sym->name);
  926.             }
  927.             pos = begin + len;
  928.             if (pos < offset) {
  929.                 len = 0;
  930.                 begin = pos;
  931.             }
  932.             pos = begin + len;
  933.             if (pos > offset+length)
  934.                 goto leave_the_loop;
  935.         }
  936.     }
  937. leave_the_loop:
  938.     *start = buf + (offset - begin);
  939.     len -= (offset - begin);
  940.     if (len > length)
  941.         len = length;
  942.     return len;
  943. }
  944.  
  945. /*
  946.  * Gets the address for a symbol in the given module.  If modname is
  947.  * NULL, it looks for the name in any registered symbol table.  If the
  948.  * modname is an empty string, it looks for the symbol in kernel exported
  949.  * symbol tables.
  950.  */
  951. unsigned long
  952. get_module_symbol(char *modname, char *symname)
  953. {
  954.     struct module *mp;
  955.     struct module_symbol *sym;
  956.     int i;
  957.  
  958.     for (mp = module_list; mp; mp = mp->next) {
  959.         if (((modname == NULL) || (strcmp(mp->name, modname) == 0)) &&
  960.             (mp->flags & (MOD_RUNNING | MOD_DELETED)) == MOD_RUNNING &&
  961.             (mp->nsyms > 0)) {
  962.             for (i = mp->nsyms, sym = mp->syms;
  963.                 i > 0; --i, ++sym) {
  964.  
  965.                 if (strcmp(sym->name, symname) == 0) {
  966.                     return sym->value;
  967.                 }
  968.             }
  969.         }
  970.     }
  971.     return 0;
  972. }
  973.  
  974. #else        /* CONFIG_MODULES */
  975.  
  976. /* Dummy syscalls for people who don't want modules */
  977.  
  978. asmlinkage unsigned long
  979. sys_create_module(const char *name_user, size_t size)
  980. {
  981.     return -ENOSYS;
  982. }
  983.  
  984. asmlinkage int
  985. sys_init_module(const char *name_user, struct module *mod_user)
  986. {
  987.     return -ENOSYS;
  988. }
  989.  
  990. asmlinkage int
  991. sys_delete_module(const char *name_user)
  992. {
  993.     return -ENOSYS;
  994. }
  995.  
  996. asmlinkage int
  997. sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
  998.          size_t *ret)
  999. {
  1000.     /* Let the program know about the new interface.  Not that
  1001.        it'll do them much good.  */
  1002.     if (which == 0)
  1003.         return 0;
  1004.  
  1005.     return -ENOSYS;
  1006. }
  1007.  
  1008. asmlinkage int
  1009. sys_get_kernel_syms(struct kernel_sym *table)
  1010. {
  1011.     return -ENOSYS;
  1012. }
  1013.  
  1014. #endif    /* CONFIG_MODULES */
  1015.